package com.fastwire.carriere.controller.impl;

import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;

import com.fastwire.carriere.common.Messages;
import com.fastwire.carriere.common.exception.ResourceException;
import com.fastwire.carriere.common.util.StringUtil;
import com.fastwire.carriere.controller.CrossConnectController;
import com.fastwire.carriere.controller.FDFrController;
import com.fastwire.carriere.controller.NetworkElementController;
import com.fastwire.carriere.controller.TerminationPointController;
import com.fastwire.carriere.dao.DAOException;
import com.fastwire.carriere.dao.DAOFactory;
import com.fastwire.carriere.dao.NEDao;
import com.fastwire.carriere.dao.NetworkInventoryDao;
import com.fastwire.carriere.hibernate.daoimpl.NetworkInventoryDaoImpl;
import com.fastwire.carriere.inventory.entity.Equipment;
import com.fastwire.carriere.inventory.entity.NetworkElement;
import com.fastwire.carriere.inventory.entity.NetworkEntityUserSpecificInfo;
import com.fastwire.carriere.inventory.vo.CrossConnectVo;
import com.fastwire.carriere.inventory.vo.EquipmentVo;
import com.fastwire.carriere.inventory.vo.FDFrVo;
import com.fastwire.carriere.inventory.vo.NetworkElementVo;
import com.fastwire.carriere.inventory.vo.SlotVo;
import com.fastwire.carriere.inventory.vo.SubrackVo;
import com.fastwire.carriere.inventory.vo.TopologicalLinkVo;
import com.fastwire.carriere.rad.controller.RadProcessControllerImp;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;

public class NetworkElementControllerImpl implements NetworkElementController {

	/** The ne dao. */
	private final NEDao neDao = DAOFactory.getInstance().getNEDao();

	private final NetworkInventoryDao inventoryDao = new NetworkInventoryDaoImpl();

	/** The cc controller. */

	/**
	 * The Class EquipmentComparator.
	 */
	public static class SlotComparator implements Comparator<SlotVo> {

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		@Override
		public int compare(SlotVo first, SlotVo second) {

			Integer firstSlot = Integer.valueOf(first.getNum());
			Integer secondSlot = Integer.valueOf(second.getNum());

			return firstSlot.compareTo(secondSlot);

		}

	}

	/**
	 * Gets the distinct ne types.
	 * 
	 * @return the distinct ne types
	 * @throws DAOException
	 *             the dAO exception
	 */
	@Override
	public List<String> getDistinctNETypes() throws DAOException {

		return neDao.findAllNETypes();

	}

	/**
	 * Search ne.
	 * 
	 * @param neVo
	 *            the ne vo
	 * @return the list
	 * @throws DAOException
	 *             the dAO exception
	 */
	@Override
	public List<String> searchNE(NetworkElementVo neVo) throws DAOException {

		List<String> neList = neDao.findNEbySearchCriteria(neVo);

		return neList;

	}

	/**
	 * Gets the nE bay faceby ne id.
	 * 
	 * @param neId
	 *            the ne id
	 * @return the nE bay faceby ne id
	 * @throws DAOException
	 *             the dAO exception
	 * @throws ResourceException
	 */
	@Override
	public NetworkElementVo getNEBayFacebyNeId(String neId)
			throws DAOException, ResourceException {

		NetworkElement networkElement = neDao.findNEbyName(neId);

		if (networkElement == null) {
			throw new ResourceException(Messages.getString(
					"message.common.dao.idnotexist.exception",
					new String[] { neId }));
		}

		NetworkEntityUserSpecificInfo neInfo = inventoryDao
				.getNetworkEntityUserSpecificInfobyNameAndType(
						networkElement.getEmsNativeName(),
						NetworkElement.class.getSimpleName());

		neId = networkElement.getName();
		NetworkElementVo neVo = new NetworkElementVo(networkElement);
		if (neInfo != null) {
			neVo.setRemarks(neInfo.getRemark());
		}
		
		CrossConnectController ccController = new CrossConnectControllerImpl();
		HashMultimap<String, CrossConnectVo> ccMap = ccController.groupCCbySlotAndPort(neId);

		FDFrController fdFrController = new FDFrControllerImpl();

		HashMultimap<String, FDFrVo> fdfrMap = fdFrController
				.groupFdFrbySlotAndPort(neId);
		HashMultimap<String, TopologicalLinkVo> tlMap = new TopologicalLinkControllerImpl()
				.groupTLbySlotAndPort(neId);

		/** The tp controller. */
		TerminationPointController tpController = new TerminationPointControllerImpl();

		List<Equipment> equipments = Lists.newArrayList(networkElement
				.getEquipments());

		java.util.regex.Pattern pattern = java.util.regex.Pattern
				.compile(".*EH=/shelf=(\\d+)");
		for (Equipment equipment : equipments) {
			String eqName = equipment.getName();
			Matcher matcher = pattern.matcher(eqName);
			if (matcher.matches()) {
				SubrackVo subrackVo = new SubrackVo(matcher.group(1));
				neVo.addSubrack(subrackVo);
			}

		}

		List<SubrackVo> subrackVos = neVo.getSubracks();
		for (SubrackVo subrackVo : subrackVos) {
			for (Equipment equipment : equipments) {
				if (subrackVo.getNum().equals(equipment.getSubrackId())
						&& StringUtil.isEmptyString(equipment
								.getEquipmentType())) {
					SlotVo slotVo = new SlotVo(equipment.getSlotId());
					subrackVo.addSlot(slotVo);
				}

			}
			List<SlotVo> slotVos = subrackVo.getSlots();
			java.util.Collections.sort(slotVos,
					new NetworkElementControllerImpl.SlotComparator());
			
			//for (SlotVo slotVo : slotVos) {
			//	for (Equipment equipment : equipments) {
			
			for (Equipment equipment : equipments) {
				for (SlotVo slotVo : slotVos) {
					if (slotVo.getNum().equals(equipment.getSlotId())
							&& !StringUtil.isEmptyString(equipment
									.getEquipmentType())) {
						EquipmentVo equipmentVo = new EquipmentVo(equipment);

						tpController.getPTPsbyNEandSlot(neId, tlMap, ccMap,
								fdfrMap, equipmentVo);
						slotVo.addEquipment(equipmentVo);

					}

				}
			}

		}

		return neVo;

	}

	@Override
	public void updateNE(NetworkElementVo neVo) throws DAOException {

		NetworkEntityUserSpecificInfo neUserSpecificInfo = inventoryDao
				.getNetworkEntityUserSpecificInfobyNameAndType(
						neVo.getNativeEmsName(),
						NetworkElement.class.getSimpleName());

		if (neUserSpecificInfo == null) {
			neUserSpecificInfo = new NetworkEntityUserSpecificInfo();
			neUserSpecificInfo.setName(neVo.getNativeEmsName());
			neUserSpecificInfo.setType(NetworkElement.class.getSimpleName());

		}

		neUserSpecificInfo.setRemark(neVo.getRemarks());

		inventoryDao
				.saveOrUpdateNetworkEntityUserSpecificInfo(neUserSpecificInfo);

	}
	
	
	// added by Jun on 20120626
    @Override
    public NetworkElementVo getRadBayFaceByIP(String ip) throws DAOException, ResourceException
    {
        return new RadProcessControllerImp().getRadByIP(ip).toNEVo();
    }


}
